package com.flutter_ecg.flutter_ecg.ecgapplication.ecgdevicescan;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.AnimationDrawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
//import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;

import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.Manifest;
import android.net.Uri;
import android.os.Bundle;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;

import java.util.ArrayList;
import java.util.List;

import com.ikinloop.iklibecgcheck.IIKEcgDeviceScanEvent;
import com.ikinloop.iklibecgcheck.IKEcgCheck;
//import com.ikinloop.iklibrarydemo.MainActivityDemo;
import com.flutter_ecg.flutter_ecg.R;
import com.flutter_ecg.flutter_ecg.ecgapplication.IKEcgCheckController;
import com.flutter_ecg.flutter_ecg.ecgapplication.IKEcgCheckInterface;
import com.flutter_ecg.flutter_ecg.ecgapplication.utils.BleAssistUtil;
import com.flutter_ecg.flutter_ecg.ecgapplication.utils.Constants;
import com.flutter_ecg.flutter_ecg.ecgapplication.utils.VoicePlayMp3;
//import android.support.v4.app.ActivityCompat;

import java.io.File;


import static android.view.View.GONE;
import static com.flutter_ecg.flutter_ecg.ecgapplication.utils.Constants.ECGDEVICEID_KEY_NAME;
import static com.flutter_ecg.flutter_ecg.ecgapplication.utils.Constants.SP_ECGDEVICEID_NAME;

import pub.devrel.easypermissions.EasyPermissions;

import com.flutter_ecg.flutter_ecg.MainActivity;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;



/*
    该类实现了心电设备的蓝牙搜索功能。
    流程描述： 启动该页面后，进入设备搜索界面，用户点击“设备搜索”， 页面调用系统蓝牙接口进行心电设备搜索，
             当搜索到设备时，用户需要点击“绑定设备” 将该设备和本手机绑定。后续系统将通过蓝牙直接连接设备的
             方式连接绑定到的心电仪设备，从而提高心电仪设备的连接效率。
             之所以要绑定设备，是因为不同Android手机在启用蓝牙搜索，在搜索性能有很大的差异，所以通过将蓝牙
             设备和手机绑定可提升连接效率，同时避免多台蓝牙设备连接同一台手机时形成的相互干扰。

 */
public class ECGDeviceScanActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, IIKEcgDeviceScanEvent, View.OnClickListener {

    private final String TAG = "ECGDeviceScanActivity:";

    private IKEcgCheck ikEcgCheck;
    private ImageView backImgeView;
    private Button scan2BondBtn, reBondBtn, bindBtn;
    private LinearLayout toBondDeviceLayout, scanningLayout, deviceFoundedLayout, deviceBondFaildLayout, bondingBondsucceedlayout;
    private Animation rotate;
    private AnimationDrawable bondingAnim;
    private ImageView bonding, scanning_scan, bonding_succeed;
    private TextView bond_faild_reason_title, bond_faild_reason, deviceSnTextView, bond_deviceID, bonding_bondsucceed, restartScan;

    private final int MSG_UI_STATE_TO_SCAN = 0X00;//未绑定，提示用户绑定
    private final int MSG_UI_STATE_SCANNING = 0X01;//搜索设备中
    private final int MSG_UI_STATE_SCAN_TIMEOUT = 0X02;//搜索超时
    private final int MSG_UI_STATE_SCAN_TIMEOUT_DELAY = 10*1000;//搜索超时时间
    private final int MSG_UI_STATE_DEVICE_FOUND = 0X03;//找到设备
    private final int MSG_UI_STATE_BOND_FAILD = 0X04;//绑定失败
    private final int MSG_UI_STATE_BONDING = 0X05;//绑定中
    private final int MSG_UI_STATE_BOND_SUCCEED = 0x06;//绑定成功

    private static final int MSG_STARTSCAN = 2900;
    private static final int STARTSCAN_DELAY = 2000;//反复开始扫描可能导致扫描失败，设置开始扫描延迟时间

    private String deviceSn;

    private VoicePlayMp3 voicePlayMp3;

    private boolean isResumed = false;

    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;

    private IKEcgCheckInterface ikEcgCheckInterface;
    private String customData;

    // 动态授权
    // android 6.0+Required permissions
    private static final int REQUEST_SDCARD = 1000;
    static final String[] PERMISSIONS = new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
    };
    private MaterialDialog materialDialog;
    private List<String> permissionsGrantedlist = new ArrayList<>();

    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == MSG_STARTSCAN) {
                int code = ikEcgCheck.IKStartEcgDeviceScan();
                Log.i(TAG, "code:::::" + code);
                switch (code) {
                    case 0:
                        playVoice(R.raw.ikinloop_press_power_btn);
                        removeMessages(MSG_UI_STATE_SCAN_TIMEOUT);
                        sendEmptyMessageDelayed(MSG_UI_STATE_SCAN_TIMEOUT, MSG_UI_STATE_SCAN_TIMEOUT_DELAY);
                        break;
                    case -4005:
                        playVoice(R.raw.ikinloop_open_ble);
                        Toast.makeText(ECGDeviceScanActivity.this, R.string.string_bluetooth_closed, Toast.LENGTH_SHORT).show();
                        updateUI(MSG_UI_STATE_TO_SCAN);
                        break;
                    case -4003:
                        Toast.makeText(ECGDeviceScanActivity.this, R.string.string_less_location_permission, Toast.LENGTH_SHORT).show();
                        break;
                }
            } else {
                if (msg.what == MSG_UI_STATE_SCAN_TIMEOUT) {
                    ikEcgCheck.IKStopEcgDeviceScan();
                }
                updateUI(msg.what);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initPermissions();
        setContentView(R.layout.activity_ecgdevice_scan);

        initView();
        initIKEcgLib();
        initBindECGDeviceId();
        initData();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!BleAssistUtil.isLocServiceEnable(this)) {
            BleAssistUtil.openLocService(this, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
        } else {
            isResumed = true;
            initIKEcgLib();
            if (TextUtils.isEmpty(deviceSn)) {
                updateUI(MSG_UI_STATE_TO_SCAN);
                playVoice(R.raw.ikinloop_please_bind_device);
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        isResumed = false;
        if (handler != null) {
            handler.removeMessages(MSG_STARTSCAN);
            handler.removeMessages(MSG_UI_STATE_SCAN_TIMEOUT);
        }
        if (ikEcgCheck != null) {
//            ikEcgCheck.IKStopEcgDeviceScan();
            ikEcgCheck.IKUninit();
            ikEcgCheck = null;
        }
        if (voicePlayMp3 != null) {
            voicePlayMp3.onPause();
        }
    }

    private void checkPermission() {

    }

    private void initView() {

        backImgeView = (ImageView) findViewById(R.id.back2Main);
        backImgeView.setOnClickListener(this);

        toBondDeviceLayout = (LinearLayout) findViewById(R.id.toBondDeviceLayout);
        scanningLayout = (LinearLayout) findViewById(R.id.scanning);
        deviceFoundedLayout = (LinearLayout) findViewById(R.id.deviceFoundedlayout);
        deviceBondFaildLayout = (LinearLayout) findViewById(R.id.device_bond_faild);
        bondingBondsucceedlayout = (LinearLayout) findViewById(R.id.bonding_bondsucceedlayout);

        bond_faild_reason_title = (TextView) findViewById(R.id.bond_faild_reason_title);
        bond_faild_reason = (TextView) findViewById(R.id.bond_faild_reason);
        deviceSnTextView = (TextView) findViewById(R.id.devicesn);
        bond_deviceID = (TextView) findViewById(R.id.bond_deviceID);
        bonding_bondsucceed = (TextView) findViewById(R.id.bonding_bondsucceed);
        restartScan = (TextView)findViewById(R.id.restartScan);
        restartScan.setOnClickListener(this);

        bonding = (ImageView)findViewById(R.id.bonding);
        scanning_scan = (ImageView)findViewById(R.id.scanning_scan);
        bonding_succeed = (ImageView)findViewById(R.id.bonding_succeed);

        scan2BondBtn = (Button) findViewById(R.id.scanDeviceToBond);
        scan2BondBtn.setOnClickListener(this);
        bindBtn = (Button) findViewById(R.id.ok_bond);
        bindBtn.setOnClickListener(this);

        reBondBtn = (Button) findViewById(R.id.bond_faild_reBond);
        reBondBtn.setOnClickListener(this);

        bondingAnim = (AnimationDrawable) getResources().getDrawable(R.drawable.ecg_bonding);
        bonding.setBackgroundDrawable(bondingAnim);

        rotate = AnimationUtils.loadAnimation(this, R.anim.ecg_scanning);
    }

    private void initIKEcgLib() {
        if (ikEcgCheck == null) {
            ikEcgCheck = IKEcgCheck.getInstance(ECGDeviceScanActivity.this);
            ikEcgCheck.IKRegistEcgDeviceScanEvent(this);
        }
//        String name = getApplicationContext().getExternalFilesDir(null).getAbsolutePath();
//        Log.i(TAG, "name::::" + name);
//        ikEcgCheck.IKSetEcgDataPath(name + File.separator + "ecg");
        ikEcgCheck.IKInit();
    }

    private void initBindECGDeviceId() {
        SharedPreferences sharedPreferences = getSharedPreferences(SP_ECGDEVICEID_NAME, Context.MODE_PRIVATE);
        deviceSn = sharedPreferences.getString(ECGDEVICEID_KEY_NAME, "");
    }

    private void initData() {
        Intent intent = getIntent();
        ikEcgCheckInterface = (IKEcgCheckInterface) intent.getSerializableExtra(Constants.IKECGINTERFACE_KEY);
        if (ikEcgCheckInterface == null) {
            Log.i(TAG, "initData:::ikEcgCheckInterface == null");
        }
        customData = intent.getStringExtra(Constants.CUSTOMDATA_KEY);
    }

    private void updateUI(int flag) {
        if (isFinishing() || isDestroyed()) {
            return;
        }
        if (null != toBondDeviceLayout) {
            toBondDeviceLayout.setVisibility(GONE);
        }
        if (null != deviceFoundedLayout) {
            deviceFoundedLayout.setVisibility(GONE);
        }
        if (null != scanningLayout) {
            scanning_scan.clearAnimation();
            scanningLayout.setVisibility(GONE);
        }
        if (null != bondingBondsucceedlayout) {
            bondingAnim.stop();
            bondingBondsucceedlayout.setVisibility(GONE);
        }
        if (null != deviceBondFaildLayout) {
            deviceBondFaildLayout.setVisibility(GONE);
        }
        switch (flag) {
            case MSG_UI_STATE_TO_SCAN:
                toBondDeviceLayout.setVisibility(View.VISIBLE);
                break;
            case MSG_UI_STATE_SCANNING:
                scanningLayout.setVisibility(View.VISIBLE);
                scanning_scan.startAnimation(rotate);
                handler.removeMessages(MSG_STARTSCAN);
                handler.sendEmptyMessageDelayed(MSG_STARTSCAN, STARTSCAN_DELAY);
                break;
            case MSG_UI_STATE_SCAN_TIMEOUT:
                deviceBondFaildLayout.setVisibility(View.VISIBLE);
                bond_faild_reason_title.setText(getResources().getString(R.string.string_device_bond_faild));
                bond_faild_reason.setText(getResources().getString(R.string.string_bond_faild_reason));
                break;
            case MSG_UI_STATE_BOND_FAILD:
                deviceBondFaildLayout.setVisibility(View.VISIBLE);
                break;
            case MSG_UI_STATE_DEVICE_FOUND:
                deviceFoundedLayout.setVisibility(View.VISIBLE);
                deviceSnTextView.setText(getResources().getString(R.string.string_device_id) + deviceSn);
                break;
            case MSG_UI_STATE_BONDING:
                bondingBondsucceedlayout.setVisibility(View.VISIBLE);
                bondingAnim.start();
                bonding_succeed.setImageResource(R.mipmap.ecg_bonding);
                bonding_bondsucceed.setText(R.string.string_device_bonding);
                bond_deviceID.setText(getResources().getString(R.string.string_device_id) + deviceSn);
                break;
            case MSG_UI_STATE_BOND_SUCCEED:
                bondingBondsucceedlayout.setVisibility(View.VISIBLE);
                bondingAnim.stop();
                bonding_succeed.setImageResource(R.mipmap.ecg_bond_succeed);
                bonding_bondsucceed.setText(R.string.string_device_bond_success);
                bond_deviceID.setText(getResources().getString(R.string.string_device_id) + deviceSn);
                gotoCheck();
                break;

        }
    }

    private void playVoice(int resID) {
        if (voicePlayMp3 == null) {
            voicePlayMp3 = new VoicePlayMp3(this);
        }
        voicePlayMp3.playVoice(resID);
    }

    private void gotoCheck() {
        VoicePlayMp3 voicePlayMp3 = new VoicePlayMp3(this);
        voicePlayMp3.playVoice(R.raw.ikinloop_bind_device_success, new VoicePlayMp3.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                if (isResumed) {
                    IKEcgCheckController.getInstance().showEcgView(ECGDeviceScanActivity.this, ikEcgCheckInterface, customData);
                }
                finish();
            }
        });
    }

    @Override
    public void onClick(View v) {

//        switch (v.getId()) {
            if (v.getId() == R.id.back2Main) {
                startActivity(new Intent(ECGDeviceScanActivity.this, MainActivity.class));
                finish();
            } else if(v.getId() == R.id.bond_faild_reBond || v.getId() == R.id.scanDeviceToBond ||  v.getId() == R.id.restartScan) {
                if (BleAssistUtil.isLocServiceEnable(this)) {
                    updateUI(MSG_UI_STATE_SCANNING);
                } else {
                    BleAssistUtil.openLocService(this, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                }
            } else if(v.getId() == R.id.ok_bond) {
                sharedPreferences = getSharedPreferences(SP_ECGDEVICEID_NAME, Context.MODE_PRIVATE);
                editor = sharedPreferences.edit();
                editor.putString(ECGDEVICEID_KEY_NAME, deviceSn).commit();
                updateUI(MSG_UI_STATE_BOND_SUCCEED);
            }
    }

    @Override
    public void OnEcgScanDeviceData(String s, String s1) {
        Log.i(TAG, "OnEcgScanDeviceData:::is Main Thread:::" + (Looper.getMainLooper() == Looper.myLooper())
                + ":::thread name:::" +Thread.currentThread().getName());
        if (!TextUtils.isEmpty(s1) && s1.contains("ikinloop ecg")) {
            if (handler != null) {
                handler.removeMessages(MSG_UI_STATE_SCAN_TIMEOUT);
            }
            ikEcgCheck.IKStopEcgDeviceScan();
            this.deviceSn = s;
            handler.removeMessages(MSG_UI_STATE_DEVICE_FOUND);
            handler.sendEmptyMessage(MSG_UI_STATE_DEVICE_FOUND);
        }
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> list) {
        permissionsGrantedlist.addAll(list);
        if (requestCode == REQUEST_SDCARD) {
            if (permissionsGrantedlist.size() != PERMISSIONS.length) {
                System.exit(0);
            }
        }
    }
    @Override
    public void onPermissionsDenied(int requestCode, List<String> list) {
        if (requestCode == REQUEST_SDCARD) {
            if (list.size() > 0) {
                if (EasyPermissions.somePermissionPermanentlyDenied(this, list)) {
                    new MaterialDialog.Builder(this)
                            .content(R.string.go_setting_desc)
                            .positiveText(R.string.go_setting)
                            .canceledOnTouchOutside(false)
                            .onPositive(new MaterialDialog.SingleButtonCallback() {
                                @Override
                                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                    Intent intent = new Intent();
                                    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
                                    if (Build.VERSION.SDK_INT >= 9) {
                                        intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                                        intent.setData(Uri.fromParts("package", getPackageName(), null));
                                    } else if (Build.VERSION.SDK_INT <= 8) {
                                        intent.setAction(Intent.ACTION_VIEW);
                                        intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
                                        intent.putExtra("com.android.settings.ApplicationPkgName", getPackageName());
                                    }
                                    startActivity(intent);
                                    System.exit(0);
                                }
                            })
                            .negativeText(R.string.string_exit).onNegative(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            System.exit(0);
                        }
                    }).show();
                    return;
                }
                final String[] permision = list.toArray(new String[list.size()]);

                new MaterialDialog.Builder(this)
                        .content(R.string.string_open_permission_desc)
                        .positiveText(R.string.string_authorization)
                        .canceledOnTouchOutside(false)
                        .onPositive(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                requiresPermission(permision, getString(R.string.string_open_permission_desc), REQUEST_SDCARD);
                            }
                        })
                        .negativeText(R.string.string_exit).onNegative(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        System.exit(0);
                    }
                }).show();
            } else {

            }
        }
    }
    private void requiresPermission(String[] permissions, String permissionsDesc, int requestCode) {
        // SDK less than 23 is authorized by default
//        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//            ActivityCompat.requestPermissions(this, permissions, requestCode);
//        } else {
            EasyPermissions.requestPermissions(this,
                    permissionsDesc, requestCode, permissions);
//        }
    }

    /**
     * Check the necessary permissions
     */
    private void initPermissions() {
        if (!EasyPermissions.hasPermissions(this, PERMISSIONS)) {//Whether the user is authorized or not
            materialDialog = new MaterialDialog.Builder(this)
                    .content(R.string.string_open_permission_desc)
                    .positiveText(R.string.string_authorization)
                    .canceledOnTouchOutside(false)
                    .onPositive(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            requiresPermission(PERMISSIONS, getString(R.string.string_open_permission_desc), REQUEST_SDCARD);
                        }
                    })
                    .negativeText(R.string.string_exit).onNegative(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            System.exit(0);
                        }
                    }).show();
        }
    }
}
